#include "MessageDispatcher.h"
#include <spdlog/spdlog.h>

namespace MessageFramework {

MessageDispatcher::MessageDispatcher(const Config& config)
    : m_config(config) {
}

void MessageDispatcher::registerHandler(const std::string& messageType, MessageHandlerPtr handler) {
    std::lock_guard<std::mutex> lock(m_mutex);

    if (!handler) {
        spdlog::warn("Attempted to register null handler for type: {}", messageType);
        return;
    }

    m_handlers[messageType] = handler;
    spdlog::info("Registered handler '{}' for message type '{}'",
                 handler->getName(), messageType);
}

void MessageDispatcher::unregisterHandler(const std::string& messageType) {
    std::lock_guard<std::mutex> lock(m_mutex);

    auto it = m_handlers.find(messageType);
    if (it != m_handlers.end()) {
        spdlog::info("Unregistered handler '{}' for message type '{}'",
                     it->second->getName(), messageType);
        m_handlers.erase(it);
    }
}

void MessageDispatcher::setDefaultHandler(MessageHandlerPtr handler) {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_defaultHandler = handler;

    if (handler) {
        spdlog::info("Set default handler: {}", handler->getName());
    }
}

void MessageDispatcher::setConfig(const Config& config) {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_config = config;
}

size_t MessageDispatcher::getHandlerCount() const {
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_handlers.size();
}

std::vector<std::string> MessageDispatcher::getRegisteredTypes() const {
    std::lock_guard<std::mutex> lock(m_mutex);

    std::vector<std::string> types;
    types.reserve(m_handlers.size());

    for (const auto& pair : m_handlers) {
        types.push_back(pair.first);
    }

    return types;
}

bool MessageDispatcher::verifyMessageSignature(const Message& message) const {
    if (m_config.secretKey.empty()) {
        spdlog::warn("Secret key not configured, skipping signature verification");
        return true;
    }

    bool valid = SignatureHelper::verify(
        message.header,
        message.body,
        m_config.secretKey,
        m_config.signatureTimeWindow
    );

    if (!valid) {
        spdlog::error("Signature verification failed for message: {} from publisher: {}",
                     message.header.messageId, message.header.publisherId);
    }

    return valid;
}

std::string MessageDispatcher::decryptMessageBody(const Message& message) const {
    if (!message.header.encrypted) {
        return message.body;  // 未加密，直接返回
    }

    if (m_config.encryptionKey.empty()) {
        spdlog::error("Message is encrypted but encryption key not configured");
        return "";
    }

    std::string plaintext = EncryptionHelper::decrypt(message.body, m_config.encryptionKey);

    if (plaintext.empty()) {
        spdlog::error("Failed to decrypt message: {}", message.header.messageId);
    }

    return plaintext;
}

MessageDispatcher::DispatchResult MessageDispatcher::dispatch(Message& message) {
    DispatchResult result;
    result.code = 0;

    // 1. 验证消息头
    if (!message.header.validate()) {
        result.code = -1;
        result.error = "Invalid message header";
        spdlog::error("Message validation failed: {}", message.header.messageId);
        return result;
    }

    // 2. 验证签名（可选）
    if (m_config.verifySignature) {
        if (!verifyMessageSignature(message)) {
            result.code = -2;
            result.error = "Signature verification failed";
            return result;
        }
    }

    // 3. 解密消息体（可选）
    if (m_config.autoDecrypt && message.header.encrypted) {
        std::string plaintext = decryptMessageBody(message);
        if (plaintext.empty()) {
            result.code = -3;
            result.error = "Decryption failed";
            return result;
        }
        message.body = plaintext;
        message.header.encrypted = false;  // 标记为已解密
    }

    // 4. 查找Handler
    MessageHandlerPtr handler;
    {
        std::lock_guard<std::mutex> lock(m_mutex);

        auto it = m_handlers.find(message.header.messageType);
        if (it != m_handlers.end()) {
            handler = it->second;
        } else {
            handler = m_defaultHandler;
        }
    }

    if (!handler) {
        result.code = -4;
        result.error = "No handler found for message type: " +
                       std::string(message.header.messageType);
        spdlog::warn("{}", result.error);
        return result;
    }

    // 5. 调用Handler处理消息
    result.handlerName = handler->getName();

    spdlog::debug("Dispatching message {} (type: {}) to handler {}",
                  message.header.messageId,
                  message.header.messageType,
                  result.handlerName);

    try {
        result.code = handler->handleMessage(message);

        if (result.code != 0) {
            spdlog::warn("Handler '{}' returned error code: {}",
                        result.handlerName, result.code);
        } else {
            spdlog::debug("Message {} processed successfully by {}",
                         message.header.messageId, result.handlerName);
        }

    } catch (const std::exception& e) {
        result.code = -5;
        result.error = "Handler exception: " + std::string(e.what());
        spdlog::error("Handler '{}' threw exception: {}",
                     result.handlerName, e.what());
    }

    return result;
}

} // namespace MessageFramework
